-- Copyright James McGill, 2010
-- Author: James McGill (jmcgill@plexer.net)

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity video_ula is
    Port ( reset : in  STD_LOGIC;
           clock_50mhz : in  STD_LOGIC;
           red : out  STD_LOGIC;
           green : out  STD_LOGIC;
           blue : out  STD_LOGIC;
           hsync : inout  STD_LOGIC;
           vsync : inout  STD_LOGIC;
			  
			  -- Debug signals
			  clock_24mhz : inout std_logic;
			  clock_8mhz : inout std_logic;
			  clock_2mhz : inout std_logic;
			  clock_reset : inout std_logic;
			  address : inout std_logic_vector(15 downto 0);
			  data : inout std_logic_vector(7 downto 0);
			  read_index_out : out std_logic_vector(7 downto 0);
			  write_index_out : out std_logic_vector(7 downto 0);
			  shift_buffer_out : out std_logic_vector(7 downto 0)
			  );
end video_ula;

architecture Behavioral of video_ula is
	 -- Generates internal clocks.
	 COMPONENT clock_generator
    PORT ( reset : in std_logic;
	        clock_50mhz : in  std_logic;
			  clock_48mhz : inout std_logic;
			  clock_24mhz : out std_logic;
           clock_8mhz : inout  std_logic;
			  clock_4mhz : inout  std_logic;
			  clock_2mhz : inout  std_logic;
           clock_1mhz : inout  std_logic;
			  locked : out std_logic);
    END COMPONENT;
	 
	 -- Mock RAM implementation.
	 COMPONENT mock_ram
    PORT(
         address : IN  std_logic_vector(15 downto 0);
         data : OUT  std_logic_vector(7 downto 0);
         clock_2mhz : IN  std_logic;
         clock_8mhz : IN  std_logic
        );
    END COMPONENT;
	 
	 -- Buffers video from the 1MHz ram to 25 MHz VGA driver.
    COMPONENT video_buffer
    PORT(
         clock_8mhz : IN  std_logic;
         clock_24mhz : IN  std_logic;
			hframe : IN std_logic;
			vframe : IN std_logic;
         data : IN  std_logic_vector(7 downto 0);
         address : OUT  std_logic_vector(15 downto 0);
			reset : IN std_logic;
         pixel : OUT  std_logic_vector(3 downto 0);
			buffer1 : OUT std_logic_vector(7 downto 0);
			buffer2 : OUT std_logic_vector(7 downto 0);
			buffer3 : OUT std_logic_vector(7 downto 0);
			buffer4 : OUT std_logic_vector(7 downto 0);
         shift_buffer_out : out std_logic_vector(7 downto 0);
			read_index_out : out std_logic_vector(7 downto 0);
			write_index_out : out std_logic_vector(7 downto 0)
        );
    END COMPONENT;
	 
	 -- VGA Controller
	 COMPONENT vga
    PORT(
         clk25 : IN  std_logic;
			reset : IN std_logic;
			red_in : in std_logic;
         red_out : OUT  std_logic;
         green_out : OUT  std_logic;
         blue_out : OUT  std_logic;
         hs_out : OUT  std_logic;
         vs_out : OUT  std_logic;
			hframe : out std_logic;
			vframe : out std_logic);
    END COMPONENT;

    -- Intra-wiring signals
	 --signal clock_24mhz : std_logic := '0';
	 signal clock_48mhz : std_logic := '0';
	 --signal clock_8mhz : std_logic := '0';
	 --signal clock_2mhz : std_logic := '0';
	 --signal address : std_logic_vector(15 downto 0);
	 --signal data : std_logic_vector(7 downto 0);
	 signal pixel : std_logic_vector(3 downto 0);
	 --signal clock_reset : std_logic := '1';
	 signal hframe : std_logic;
	 signal vframe : std_logic;

begin
   clock_generator_instance : clock_generator PORT MAP (
          reset => reset,
          clock_50mhz => clock_50mhz,
			 clock_48mhz => clock_48mhz,
			 clock_24mhz => clock_24mhz,
          clock_8mhz => clock_8mhz,
			 clock_4mhz => open,
			 clock_2mhz => clock_2mhz,
          clock_1mhz => open,
          locked => open
        );

   mock_ram_instance : mock_ram PORT MAP (
          address => address,
          data => data,
          clock_2mhz => clock_2mhz,
          clock_8mhz => clock_8mhz
        );
		  
	video_buffer_instance : video_buffer PORT MAP (
          clock_8mhz => clock_8mhz,
          clock_24mhz => clock_50mhz,
			 reset => clock_reset,
			 hframe => hframe,
			 vframe => vframe,
          data => data,
          address => address,
          pixel => pixel,
			 buffer1 => open,
			 buffer2 => open,
			 buffer3 => open,
			 buffer4 => open,
          shift_buffer_out => shift_buffer_out,
          read_index_out => read_index_out,
          write_index_out => write_index_out			 
        );
		  
	 vga_instance : vga PORT MAP (
          clk25 => clock_50mhz,
			 reset => clock_reset,
			 red_in => pixel(0),
          red_out => red,
          green_out => green,
          blue_out => blue,
          hs_out => hsync,
          vs_out => vsync,
			 hframe => hframe,
			 vframe => vframe
        );
		  
	  -- Debugging 
	  --clock_24mhz <= clock_24mhz;
	  --clock_8mhz : out std_logic;
	  --clock_2mhz : out std_logic;
	  --clock_reset : out std_logic;
	  --address : out std_logic_vector(15 downto 0);
	  --data : out std_logic_vector(7 downto 0)
		  
  clock_reset <= '0';
  -- Synchronize reset.
  --process (clock_2mhz)
  --begin
  --  if (clock_2mhz'event and clock_2mhz = '1') then
--	   clock_reset <= '0';
	 --end if;
  --end process;

end Behavioral;

